home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / pascal / SWAG9605.DDD / 0140_Earth Invaders Game.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-05-31  |  16.8 KB  |  835 lines

  1. {
  2. ========================================================
  3.  
  4.        EARTH INVADERS (Original LCD game by CGL 1982..)
  5.        (I feel a copyright wangle coming on - NOT!)
  6.  
  7. --------------------------------------------------------
  8.  
  9. PC CONVERSION EXCLUSIVELY FOR SWAG, BY SCOTT TUNSTALL 1996
  10.    (But why? ;) )
  11.  
  12. Reqs: Turbo Pascal 5.5 +
  13.       CGA
  14.       Good technique in chatting up women
  15.  
  16.  
  17. ==========
  18.  
  19. DISCLAIMER
  20.  
  21. ----------
  22.  
  23. I (Scott Tunstall) am not responsible if this program causes any
  24. damage to ANY hardware or software part of the computer system it
  25. runs on or detriment to mental health caused (finding any bugs I
  26. may have missed) OK?.
  27.  
  28. You can alter/delete or even ADD (if you're sad enough) new bits
  29. to the program just as long as I am credited with the ORIGINAL
  30. version. You are not permitted to distribute the original or
  31. changed code for monetary gain however.
  32.  
  33.  
  34.  
  35. ========
  36.  
  37. FORENOTE
  38.  
  39. --------
  40.  
  41. I was playing a hand held LCD game one saturday and it was actually
  42. simple to play, yet quite addictive. Unusual for a hand held.
  43.  
  44. Anyway, being the sad idiot that I am, I decided to convert it to
  45. Pascal, and give y' all a taste of the game. Hope you enjoy playing
  46. it, I certainly almost did ! (in between debugging)
  47.  
  48.  
  49.  
  50. ========
  51.  
  52. THE GAME
  53.  
  54. --------
  55.  
  56. Aliens appear on the screen, you must dig holes for them to fall in.
  57. If an alien falls in you must bury it in the hole, but beware! If
  58. an alien touches an alien in a hole it is helped out and will jump
  59. at the human!!!
  60.  
  61. Maybe, I will write a two player version of this game. After the Bsc,
  62. perhaps?.
  63.  
  64.  
  65.  
  66. Keys are (until I write a define key routine)
  67.  
  68. CTRL = Dig hole
  69. ALT  = Fill hole in (to kill an alien you do this)
  70.  
  71. CURSOR UP    = Move up
  72. CURSOR DOWN  = Move down
  73. CURSOR LEFT  = Move left
  74. CURSOR RIGHT = Move right
  75.  
  76.  
  77. Err... your guy is represented by a 'x' and the aliens are all 's (until
  78. I actually draw up some GFX! (Knowing me - NEVER!).
  79.  
  80. Hell, what do you want from me, SVGA? ;^)
  81.  
  82.  
  83.  
  84. =============
  85.  
  86. FOR YOU TO DO
  87.  
  88. -------------
  89.  
  90. Add a title screen
  91. Better sound (even samples)
  92. Check if all aliens are dead
  93. 2/3/4 player mode
  94. A lager drinking section.... (please! I've always wanted to see a game
  95.                               with this in it!)
  96.  
  97.  
  98.  
  99.  
  100. =====
  101.  
  102. NOTES
  103.  
  104. -----
  105.  
  106. NewKbdInt (The Multiple key reader) is appended to the bottom of
  107. this source so it can be compiled. I didn't write it - Lou Duchez
  108. did. Credits to him....
  109.  
  110. }
  111.  
  112.  
  113.  
  114.  
  115. uses crt, nwkbdint;     { Present in the SWAG }
  116.  
  117.  
  118.  
  119.  
  120. {
  121.  
  122. All objects are mapped directly to the map,
  123. no external data types are used to contain Aliens X,Y coordinates
  124.  
  125.  
  126.  
  127. 0 = Empty
  128. 1 = Wall
  129. 2 = Human
  130. 3 = Quarter Dug Hole 1
  131. 4 = Half Dug Hole 2
  132. 5 = Three Quarter Dug Hole 3
  133. 6 = Fully Dug Hole
  134.  
  135. 20..40 = Alien (In various stages of falling.. 40 = Not inhole)
  136. }
  137.  
  138.  
  139.  
  140.  
  141. const Empty               = 0;
  142.       Wall                = 1;
  143.       Human               = 2;
  144.       QuarterDugHole      = 3;
  145.       HalfDugHole         = 4;
  146.       ThreeQuarterDugHole = 5;
  147.       FullyDugHole        = 6;
  148.  
  149.       AlienFilledIn         = 19;
  150.       AlienCompletelyBuried = 30;
  151.       AlienBeginsClimbOut   = 36;
  152.       AlienAlmostBuried     = 40;
  153.       AlienHalfBuried       = 50;
  154.       NormalAlien           = 70;
  155.       AlienTripped          = NormalAlien-5;
  156.  
  157.       Amateur             = 1;
  158.       Pro                 = 2;
  159.       Kamikaze            = 3;  { Not implemented, Pro is hard enough! }
  160.  
  161.       UpKey               = 72;
  162.       DownKey             = 80;
  163.       LeftKey             = 75;
  164.       RightKey            = 77;
  165.       DigKey              = 29;
  166.       FillKey             = 56;
  167.  
  168.  
  169.  
  170.  
  171.  
  172. var map         : array[1..7,1..5] of byte;    { Playfield }
  173.     killedplayer  : boolean;
  174.     SkillLevel  : byte;
  175.     GameLevel   : byte;
  176.     GameSpeed   : byte;
  177.     AlienPause  : byte;
  178.  
  179.  
  180.     HumanX, HumanY : byte;
  181.     Currx,Curry : byte;
  182.  
  183.  
  184.  
  185.  
  186.  
  187. type AlienInfo      = record
  188.      AlienState     : byte;
  189.      AlienX, AlienY : byte;
  190.      end;
  191.  
  192.  
  193.  
  194.  
  195. {
  196. The following values are written to the map, the values contained
  197. may be:
  198.  
  199. 0 = Empty
  200. 1 = Wall
  201. 2 = Human
  202. 3 = Quarter Dug Hole 1
  203. 4 = Half Dug Hole 2
  204. 5 = Three Quarter Dug Hole 3
  205. 6 = Fully Dug Hole
  206.  
  207. 20 + = Reserved for aliens, see constants above
  208.  
  209.  
  210. Therefore, if map[1,1] was 3 then that means a Quarter Dug hole
  211. is at the top left of the map.
  212.  
  213. }
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224. procedure initmap;
  225. var x:byte;
  226.     y:byte;
  227.  
  228. begin
  229.      {
  230.      Erase all of map. If you're sad enough, like me, then you
  231.      could design small maps, or even extend 'em to fill the
  232.      entire screen.
  233.      }
  234.  
  235.  
  236.      for y:=1 to 5 do
  237.          for x:=1 to 7 do
  238.          map[x,y]:=empty;
  239.  
  240.      {
  241.      Set Walls
  242.      }
  243.  
  244.  
  245.      for x:=1 to 3 do
  246.          begin
  247.          map[x *2,2]:=Wall;
  248.          map[x *2,4]:=Wall;
  249.      end;
  250.  
  251.      {
  252.      Determine game speed
  253.      }
  254.  
  255.      case SkillLevel of
  256.      Amateur  : GameSpeed:=6;
  257.      Pro      : GameSpeed:=2;    { Life expectancy - 3 seconds }
  258.      Kamikaze : GameSpeed:=1;    { Life expectancy - NIL! }
  259.      end;
  260.  
  261.      AlienPause:=GameSpeed;
  262.  
  263.  
  264.      {
  265.      Now place aliens
  266.      }
  267.  
  268.  
  269.  
  270.      for x:=1 to 3 do
  271.          map[x*2,1]:=NormalAlien;
  272.  
  273.      if gamelevel > 1 then
  274.         begin
  275.         map[2,3]:=NormalAlien;
  276.         map[6,3]:=NormalAlien;
  277.      end;
  278.  
  279.  
  280.      if gamelevel > 2 then
  281.         map[4,3]:=NormalAlien;
  282.  
  283.  
  284.      {
  285.      Place human
  286.      }
  287.  
  288.      HumanX:=4;
  289.      HumanY:=5;
  290.  
  291.      map[HumanX,HumanY]:=Human;
  292.  
  293. end;
  294.  
  295.  
  296.  
  297.  
  298.  
  299. { The following 2 procedures are NOT mine; they were written by
  300.   Robert E. Swart and cut and pasted to this routine
  301.  
  302.   I modified these routines for my own use!
  303. }
  304.  
  305.  
  306.  
  307. procedure Lines200;
  308.     { Set 200 scanlines on VGA display }
  309.     InLine(
  310.       $B8/$01/$00/  {  mov   AX,$0001  }
  311.       $CD/$10/      {  int   $10       }
  312.       $B8/$00/$12/  {  mov   AX,$1200  }
  313.       $B3/$30/      {  mov   BL,$30    }
  314.       $CD/$10);     {  int   $10       }
  315.  
  316.  
  317.     procedure Font8x16;
  318.     { Set 8x16 VGA-font on VGA display }
  319.     InLine(
  320.       $B8/$01/$00/  {  mov   AX,$0001  }
  321.       $CD/$10/      {  int   $10       }
  322.       $B8/$14/$11/  {  mov   AX,$1114  }
  323.       $B3/$00/      {  mov   BL,0      }
  324.       $CD/$10);     {  int   $10       }
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332. procedure SetCurPos(newx, newy: byte);
  333. begin
  334.      currx:=newx-1;             { Conv phys to log }
  335.      curry:=newy-1;
  336. end;
  337.  
  338.  
  339.  
  340. { Faster than using the write command for only one char }
  341.  
  342. procedure text(TheChar: char; TheColour: byte);
  343. begin
  344.      memw[$b800: (curry * 80) + (currx SHL 1)]:=word (ord(TheChar)+(TheColour SHL 8));
  345. end;
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354. {
  355. ====================================================================
  356.  
  357. Draw the game screen.
  358.  
  359. Note: All of the aliens actually exist on map, they are not simply
  360. sprites overlaid on the map during draw time, so in theory you could
  361. fill the entire map with aliens.... Have fun!
  362.  
  363. --------------------------------------------------------------------
  364. }
  365.  
  366.  
  367.  
  368. procedure DrawMap;
  369. var x, y : byte;
  370.  
  371. begin
  372.      for y:=1 to 5 do
  373.          for x:=1 to 7 do
  374.          begin
  375.          SetCurPos(x,y);
  376.  
  377.          case map[x,y] of
  378.          Empty               : text(' ', BLACK);
  379.          Wall                : text('#', BLUE);
  380.          Human               : text('x', RED);
  381. AlienCompletelyBuried..
  382. (AlienBeginsClimbOut-1)      : text(#1, random(7) OR 1);
  383.  
  384. AlienBeginsClimbout..
  385. (NormalAlien-1)              : text(#1, GREEN);
  386.  
  387.          NormalAlien         : text(#2, GREEN);
  388.          QuarterDugHole      : text('.',LIGHTGRAY);
  389.  
  390.          HalfDugHole,
  391.          ThreeQuarterDugHole : text('o', LIGHTGRAY);
  392.          FullyDugHole        : text('O',LIGHTGRAY);
  393.          end;
  394.      end;
  395. end;
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403. {
  404. ==============================================================
  405.  
  406. Free an alien that may be trapped at maybex, maybey on the map
  407.  
  408.  
  409. --------------------------------------------------------------
  410. }
  411.  
  412.  
  413.  
  414. Procedure ReleaseAlien(maybex, maybey: byte);
  415. var TheObject: byte;
  416.  
  417. begin
  418.      if (maybex > 0) and (maybex < 8) and (maybey > 0) and (maybey < 6) then
  419.         begin
  420.         theObject:=map[maybex, maybey];
  421.         if (theObject> AlienFilledIn) And
  422.            (theobject < NormalAlien) Then
  423.            map[maybex, maybey]:=NormalAlien;
  424.         end;
  425. end;
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436. procedure MoveAliens;
  437. var AlienArray        : Array[1..10] of AlienInfo;
  438.     x, y, TheObject   : byte;
  439.     index             : byte;
  440.     noblank           : boolean;
  441.     NewDir,
  442.     NewXp,
  443.     NewYp,
  444.     ObjectHit         : byte;
  445.  
  446.  
  447. begin
  448.      dec(AlienPause);
  449.      if AlienPause = 0 Then
  450.  
  451.      { Find all aliens on the map, and remember where they
  452.        are so they can be moved later.
  453.      }
  454.  
  455.  
  456.          Begin
  457.          AlienPause:=GameSpeed;
  458.  
  459.          index:=1;
  460.          For y:=1 to 5 do
  461.              For x:=1 to 7 do
  462.                  begin
  463.                  TheObject:=map[x,y];
  464.                  If (TheObject >=AlienCompletelyBuried) And
  465.                     (TheObject <=NormalAlien) Then
  466.                     With AlienArray[index] do
  467.                     Begin
  468.                     AlienState :=TheObject;
  469.                     AlienX     :=x;
  470.                     AlienY     :=y;
  471.                     Inc(index);
  472.                     End;
  473.  
  474.              end;
  475.  
  476.  
  477.          { Now that an array of aliens has been built up,
  478.            move em out! Also note x is being re-used. }
  479.  
  480.          for x:=(index-1) downto 1 do
  481.          With AlienArray[x] do
  482.              begin
  483.              if AlienState = NormalAlien Then
  484.                 Begin
  485.  
  486.                 { An alien can free it's trapped brother }
  487.  
  488.                 releasealien(AlienX-1,AlienY);
  489.                 releasealien(AlienX+1,AlienY);
  490.                 releasealien(AlienX,AlienY-1);
  491.                 releasealien(AlienX,AlienY+1);
  492.  
  493.                 {
  494.                 =============================
  495.  
  496.                 Move alien in a direction
  497.  
  498.                 -----------------------------
  499.                 }
  500.  
  501.  
  502.                 NewDir :=random(5)+1;
  503.                 NewXp  :=AlienX;
  504.                 NewYp  :=AlienY;
  505.  
  506.                 case NewDir of
  507.                 1: if newxp <> 1 then dec(newxp);
  508.                 2: if newxp <> 7 then inc(newxp);
  509.                 3: if newyp <> 1 then dec(newyp);
  510.                 4: if newyp <> 5 then inc(newyp);
  511.                 5..6: if newyp < humany then         { A wee bit of AI :) }
  512.                       inc(newyp)
  513.                    else
  514.                        if newyp > humany then
  515.                           dec(newyp);
  516.  
  517.                 end;
  518.  
  519.  
  520.                 {
  521.                 }
  522.  
  523.  
  524.                 noblank:=false;
  525.                 objecthit:=map[newxp,newyp];
  526.  
  527.                 case objecthit of
  528.                 empty               : map[newxp, newyp]:=NormalAlien;
  529.                 human               : killedplayer:=true;
  530.                 QuarterDugHole      : map[newxp, newyp]:=AlienTripped;
  531.                 HalfDugHole         : map[newxp, newyp]:=AlienHalfBuried;
  532.                 ThreeQuarterDugHole : map[newxp, newyp]:=AlienAlmostBuried;
  533.                 FullyDugHole        : map[newxp, newyp]:=AlienCompletelyBuried;
  534.                 else
  535.                     noblank:=true;
  536.                 end;
  537.  
  538.                 {
  539.                 Noblank, when set FALSE means the alien has moved
  540.                 and the area where the alien was on the map shall be
  541.                 set empty.
  542.                 }
  543.  
  544.  
  545.                 if not noblank then
  546.                    map[AlienX, AlienY]:=Empty;
  547.  
  548.                 { I used this for debugging. I thought it was cos
  549.                   the SWAG keyboard handler was dodgy, but it wasn't
  550.                   - my code was !!! }
  551.  
  552.                 { gotoxy(1,24); write (chr (random(128)+32)); }
  553.  
  554.                 end
  555.              else
  556.                  If AlienState < NormalAlien Then
  557.                     Begin
  558.                     TheObject:=Map[AlienX, AlienY];
  559.                     Inc(TheObject,1);
  560.                     If TheObject > NormalAlien Then
  561.                        TheObject:=NormalAlien;
  562.  
  563.                     Map[AlienX,AlienY]:=TheObject;
  564.                     End;
  565.              end;
  566.          end;
  567.  
  568.  
  569.  
  570. end;
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578. {
  579. ======================
  580.  
  581. Guess what this does ?
  582.  
  583. ----------------------
  584. }
  585.  
  586.  
  587.  
  588.  
  589. Procedure DigHole(holex, holey: byte);
  590. var TheObject: byte;
  591.  
  592. Begin
  593.  
  594.  
  595.      TheObject:=Map[holex, holey];
  596.      If TheObject = Empty Then
  597.         Map[HoleX,Holey]:=QuarterDugHole
  598.      Else
  599.          If (TheObject >= QuarterDugHole)
  600.          And (TheObject < FullyDugHole) Then
  601.              Begin
  602.              Sound(50);
  603.              Delay(100);
  604.              NoSound;
  605.              Inc(Map[HoleX,HoleY]);
  606.              End;
  607. End;
  608.  
  609.  
  610.  
  611.  
  612.  
  613. {
  614. ==============================
  615.  
  616. FILL IN A HOLE / BURY AN ALIEN
  617.  
  618. ------------------------------
  619. }
  620.  
  621.  
  622.  
  623.  
  624. Procedure FillHole(holex, holey:byte);
  625. Var TheObject: byte;
  626.  
  627. Begin
  628.  
  629.  
  630.      TheObject:=Map[Holex, Holey];
  631.      If (TheObject >= QuarterDugHole) And (TheObject <= FullyDugHole) Then
  632.         Begin
  633.         Sound(20);
  634.         Delay(100);
  635.         NoSound;
  636.         Dec(Map[HoleX, HoleY]);
  637.         If Map[HoleX, HoleY] < QuarterDugHole Then
  638.            Map[HoleX, HoleY]:=Empty;
  639.         End
  640.      Else
  641.          If (TheObject >=AlienFilledIn) And
  642.          (TheObject <= AlienBeginsClimbOut) Then
  643.             Begin
  644.             Sound(90);
  645.             Delay(40);
  646.             NoSound;
  647.             Dec(Map[HoleX,HoleY],1);
  648.             If Map[HoleX,HoleY] <= AlienFilledIn Then
  649.                Map[HoleX,HoleY]:=Empty;
  650.             End;
  651. End;
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660. {
  661. =======================================
  662.  
  663. Try and move the human to a new square.
  664.  
  665. If he walks into an alien though....
  666.  
  667. ---------------------------------------
  668. }
  669.  
  670.  
  671.  
  672. Procedure TryMove(newx, newy: byte);
  673. Var TheObject: byte;
  674.  
  675. Begin
  676.      TheObject:=Map[NewX, NewY];
  677.      If TheObject = Empty Then
  678.         Begin
  679.         Map[HumanX, HumanY]:=Empty;
  680.         Map[NewX, NewY]:=Human;
  681.         HumanX:=newx;
  682.         HumanY:=newy;
  683.         End
  684.      Else
  685.          If TheObject = NormalAlien Then
  686.             killedplayer:=true;
  687. End;
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697. {
  698. =====================
  699.  
  700. MOVE THE HUMAN AROUND
  701.  
  702. ---------------------
  703. }
  704.  
  705.  
  706.  
  707.  
  708.  
  709. Procedure MovePlayers;
  710.  
  711. var currpx, currpy     : byte;
  712.     digging, burying : boolean;
  713.  
  714. Begin
  715.      currpx:=humanx;
  716.      currpy:=humany;
  717.  
  718.      digging:=false;
  719.      burying:=false;
  720.  
  721.      if (keydown[DigKey]) then
  722.         digging:=true
  723.      else
  724.          if (keydown[FillKey]) then
  725.             burying:=true;
  726.  
  727.  
  728.      if keydown[UpKey] and (currpy <>1) then
  729.         begin
  730.         if digging or burying then
  731.            begin
  732.            if digging then
  733.               dighole(currpx, currpy-1)
  734.            else
  735.                fillhole(currpx, currpy-1);
  736.            end
  737.         else
  738.             trymove(currpx,currpy-1);
  739.         end
  740.      else
  741.          if keydown[DownKey] and (currpy <>5) then
  742.             begin
  743.             if digging or burying then
  744.                begin
  745.                if digging then
  746.                   dighole(currpx, currpy+1)
  747.                else
  748.                    fillhole(currpx, currpy+1);
  749.                end
  750.             else
  751.                 trymove(currpx,currpy+1);
  752.             end
  753.          else
  754.              if keydown[LeftKey] and (currpx <>1) then
  755.                 begin
  756.                 if digging or burying then
  757.                    begin
  758.                    if digging then
  759.                       dighole(currpx-1, currpy)
  760.                    else
  761.                        fillhole(currpx-1, currpy);
  762.                    end
  763.                 else
  764.                     trymove(currpx-1,currpy);
  765.                 end
  766.              else
  767.                  if keydown[RightKey] and (currpx <>7) then
  768.                     begin
  769.                     if digging or burying then
  770.                        begin
  771.                        if digging then
  772.                           dighole(currpx+1, currpy)
  773.                        else
  774.                            fillhole(currpx+1, currpy);
  775.                        end
  776.                     else
  777.                         trymove(currpx+1,currpy);
  778.                     end;
  779. end;
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796. begin
  797.      randomize;
  798.      skilllevel:=amateur;
  799.      gamelevel:=1;
  800.  
  801.      initmap;                   { Set map up }
  802.  
  803.      Lines200;
  804.      Font8x16;
  805.  
  806.      hookkeyboardint;
  807.  
  808.      repeat
  809.            drawmap;
  810.  
  811.            movealiens;
  812.            moveplayers;
  813.            delay(125);
  814.  
  815.  
  816.      until keydown[1] or killedplayer ;
  817.      textmode(CO80);
  818.  
  819.      unhookkeyboardint;
  820. end.
  821.  
  822.  
  823.  
  824.  
  825. {
  826. If you actually play this game in it's unaltered state.. my commiserations! 
  827. Contact address: CG93SAT@IBMRISC.DCT.AC.UK
  828.  
  829. What I'd like to see more of in the SWAG are humour games... the Amiga
  830. has loads (cos it's a joke machine - just kidding, I own one too)
  831.  
  832. Remember to write that lager drinking sim now ;)  !!!
  833. }
  834.  
  835.